//
//  UserManager.m
//  MSHD
//
//  Created by HCreater on 2017/12/7.
//  Copyright © 2017年 HCreater. All rights reserved.
//

#import "UserManager.h"

#import "CommonMsgData.h"

@interface UserManager()

@property (nonatomic, readwrite, assign) BOOL isNeedUpdate;

@property (nonatomic, readwrite, copy) UserData* userData;
@property (nonatomic, readwrite, copy) NSString* userToken;

@property (nonatomic, readwrite, assign) NSInteger unReadMsgNum;

@property (nonatomic, readwrite, strong) RACCommand* cleanUnReadMsgCmd;

@end

@implementation UserManager

MHSingletonM(UserManager);

NSString* UM_appLanguage = @"CH";

//+ (void)checkUserToken:(VoidBlock_id)block
//{
//    NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
//    NSString* strUserToken = [userDefaults objectForKey:@"UserToken"];
//
//    if ([strUserToken isNotBlank])
//    {
//        @weakify(self)
//        /// 发起请求
//        [[AFNetWorkUtils racPOSTWthURL:url_interface_userMessage params:[NSString dic2url:interface_param_userMessage(strUserToken)]] subscribeNext:^(id x) {
//            //成功返回(result class is NSDictionary)
//
//            @strongify(self);
//            HDUser* hdLogin = [HDUser modelWithJSON:x[@"result"]];
//
//            block(@YES);
//
//        } error:^(NSError *error) {
//            //错误处理
//
//            [userDefaults setObject:@"" forKey:@"UserToken"];
//            [userDefaults synchronize];
//
//            block(@NO);
//        }];
//    }
//    else
//    {
//        block(@NO);
//    }
//}

- (id)init
{
    self = [super init];
    
    if (self)
    {
        [self reset];
        [self initUserConfig];
        [self initRAC];
    }
    
    return self;
}

- (void)reset
{
    _userData = nil;
    _userToken = @"";
    _unReadMsgNum = 0;
}

- (void)initUserConfig
{
    //是否有已登录
    NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
    NSString* strUserToken = [userDefaults objectForKey:@"UserToken"];
//    strUserToken = @"619DB322B2F7B9365C31FC9774FF2FA7";
//    strUserToken = @"348802CEEE3E15CEE0C1CDCA1E0F8086";
    self.userToken = strUserToken;
    
    _isNeedUpdate = NO;
}

- (void)initRAC
{
    @weakify(self)
    
    self.cleanUnReadMsgCmd = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input)
    {
        @strongify(self);
        
        return [self requestCleanUnReadMsgSignal];
    }];
    
#pragma mark -- 用户信息
    RACSignal* userDataChangeSignal = [[RACObserve(self, userData) distinctUntilChanged] replay];
    
    [[userDataChangeSignal skip:1] subscribeNext:^(id x)
    {
        @strongify(self);

        UserData* curUserData = x;

        self.userToken = curUserData!=nil?curUserData.ticket:@"";
    }];
    
#pragma mark -- 用户token改变
    RACSignal* userTokenChangeSignal = [[RACObserve(self, userToken) distinctUntilChanged] replay];
    
    AFNetWorkUtils* netUtil = [AFNetWorkUtils sharedAFNetWorkUtils];
    netUtil.customReqHeader[@"Authorization"] = @"BasicAuth";
    
    [[[[[userTokenChangeSignal skip:1] doNext:^(id x)
    {
        @strongify(self)
        
        NSString* curUserToken = x;
        
        if ([curUserToken isNotBlank])
        {
            // 请求头设置
            netUtil.customReqHeader[@"Authorization"] = HCStrFormat(@"BasicAuth %@", curUserToken);
        }
        else
        {
            netUtil.customReqHeader[@"Authorization"] = @"BasicAuth";
        }
        
        NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
        [userDefaults setObject:curUserToken forKey:@"UserToken"];
        [userDefaults synchronize];
    }] filter:^BOOL(id value) {
        @strongify(self)
        
        return [self.userToken isNotBlank];
    }] flattenMap:^RACStream *(id value) {
        
        @strongify(self)
        
        return [self requestUnReadMsgSignal];
    }] subscribeNext:^(id x) {
        
    }];
    
    RACSignal* updateSignal = [[[[RACObserve(self, isNeedUpdate) distinctUntilChanged] filter:^BOOL(id value) {
        @strongify(self)
        
        return [value boolValue] && [self.userToken isNotBlank];
    }] map:^id(id value) {
        @strongify(self);
        
        return self.userToken;
    }] replay];
    
    RACSignal* mergeSignal = [RACSignal merge:@[updateSignal]];
    [[mergeSignal flattenMap:^RACStream *(id value) {
        @strongify(self);
        
        @weakify(self);
        return [[self requestUserInfoSignal] filter:^BOOL(id value2) {
            if ([value2 boolValue])
            {
                NSLog(@"用户信息获取成功");
            }
            else
            {
                NSLog(@"用户信息获取失败");
            }
            
            return [value2 boolValue];
        }];
    }] subscribeNext:^(id x) {
        
        @strongify(self)
        self.isNeedUpdate = NO;
    }];
    
#pragma mark -- 未读消息
    [[RACObserve(self, unReadMsgNum) deliverOnMainThread] subscribeNext:^(id x) {
       @strongify(self);
        
        [[NSNotificationCenter defaultCenter] postNotificationName:Notify_Tabbar_BadgeNum object:@{@"ShowIndex":@1, @"BadgeNum":@(self.unReadMsgNum)}];
    }];
    
#pragma mark -- 支付推送
    [[[[NSNotificationCenter defaultCenter] rac_addObserverForName:Notify_Pay_Push object:nil]
      filter:^BOOL(id value)
    {
        @strongify(self);
        
        return [self isLogined];
    }] subscribeNext:^(id x)
    {
        @strongify(self);
        
        [self updateUserInfo];
    }];
}

- (void)reupdate
{
    NSString* curUserToken = _userToken;
    
    AFNetWorkUtils* netUtil = [AFNetWorkUtils sharedAFNetWorkUtils];
    
    if ([curUserToken isNotBlank])
    {
        // 请求头设置
        netUtil.customReqHeader[@"Authorization"] = HCStrFormat(@"BasicAuth %@", curUserToken);
    }
    else
    {
        netUtil.customReqHeader[@"Authorization"] = @"";
    }
}

- (void)clean
{
    self.userData = nil;
    self.userToken = @"";
    
    NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
    [userDefaults setObject:self.userToken forKey:@"UserToken"];
    [userDefaults synchronize];
    
    [self reupdate];
}

- (BOOL)isLogined
{
    return _userData!=nil && [_userData.ticket isNotBlank];
}

- (BOOL)isHaveUserToken
{
    return [self.userToken isNotBlank];
}

- (void)logonOut
{
//    [self userUnBindDevToken];
    
    if (self.userData)
    {
        [[UMManager sharedUMManager] removeAlias:_userData.userName];
    }
    
    [self reset];

    DataManager* dataMgr = [DataManager sharedDataManager];
    [dataMgr cleanDBMgr];
    
    [[NSNotificationCenter defaultCenter] postNotificationName:Notify_Logout object:nil];
}

- (void)saveUserData:(UserData*)userData
{
    self.userData = userData;
    
    NSString* dbName = HCStrFormat(@"%@.sqlite", self.userData.userName);
    DataManager* dataMgr = [DataManager sharedDataManager];
    [dataMgr createDBMgr:dbName];
    
    [[UMManager sharedUMManager] bindAlias:self.userData.userName];
    
    [[NSNotificationCenter defaultCenter] postNotificationName:Notify_LoginSuc object:nil];
}

- (void)updateUserInfo
{
    self.isNeedUpdate = NO;
    self.isNeedUpdate = YES;
}

- (void)cleanUnReadMsg
{
    [self.cleanUnReadMsgCmd execute:nil];
}

//- (void)vercodeSave:(NSString *)vercode
//{
//    self.vercode = vercode;
//}
//
//- (void)waitGetLoginVerCode
//{
//    _loginVerCodeWaitTime = 60;
//
//    __block int timeout = _loginVerCodeWaitTime + 1;
//    //获取全局队列
//    dispatch_queue_t global = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//    //创建一个定时器，并将定时器的任务交给全局队列执行(并行，不会造成主线程阻塞)
//    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, global);
//    // 设置触发的间隔时间
//    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
//    //1.0 * NSEC_PER_SEC  代表设置定时器触发的时间间隔为1s
//    //0 * NSEC_PER_SEC    代表时间允许的误差是 0s
//
//    //block内部 如果对当前对象的强引用属性修改 应该使用__weak typeof(self)weakSelf 修饰  避免循环调用
//    __weak typeof(self)weakSelf = self;
//    //设置定时器的触发事件
//    dispatch_source_set_event_handler(timer, ^{
//        //倒计时  刷新button上的title ，当倒计时时间为0时，结束倒计时
//        //1. 每调用一次 时间-1s
//        timeout --;
//
//        weakSelf.loginVerCodeWaitTime = timeout;
//
//        //2.对timeout进行判断时间是停止倒计时，还是修改button的title
//        if (timeout <= 0) {
//            //停止倒计时，button打开交互，背景颜色还原，title还原
//            //关闭定时器
//            dispatch_source_cancel(timer);
//            //MRC下需要释放，这里不需要
//            // dispatch_realse(timer);
//            //button上的相关设置
//            //注意: button是属于UI，在iOS中多线程处理时，UI控件的操作必须是交给主线程(主队列)
//            //在主线程中对button进行修改操作
//            //            dispatch_async(dispatch_get_main_queue(), ^{
//            //                weakSelf.downBtn.userInteractionEnabled = YES;//开启交互性
//            //                weakSelf.downBtn.backgroundColor = [UIColor yellowColor];
//            //                [weakSelf.downBtn setTitle:@"获取验证码" forState:UIControlStateNormal];
//            //            });
//        }else {
//            //处于正在倒计时，在主线程中刷新button上的title，时间-1秒
//            //            dispatch_async(dispatch_get_main_queue(), ^{
//            //                NSString * title = [NSString stringWithFormat:@"%d秒后重新获取验证码",timeout];
//            //                [weakSelf.downBtn setTitle:title forState:UIControlStateNormal];
//            //                weakSelf.downBtn.userInteractionEnabled = NO;//关闭交互性
//            //            });
//        }
//    });
//    dispatch_resume(timer);
//}
//
//- (void)waitGetVerCode
//{
//    _verCodeWaitTime = 60;
//
//    __block int timeout = _verCodeWaitTime + 1;
//    //获取全局队列
//    dispatch_queue_t global = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//    //创建一个定时器，并将定时器的任务交给全局队列执行(并行，不会造成主线程阻塞)
//    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, global);
//    // 设置触发的间隔时间
//    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
//    //1.0 * NSEC_PER_SEC  代表设置定时器触发的时间间隔为1s
//    //0 * NSEC_PER_SEC    代表时间允许的误差是 0s
//
//    //block内部 如果对当前对象的强引用属性修改 应该使用__weak typeof(self)weakSelf 修饰  避免循环调用
//    __weak typeof(self)weakSelf = self;
//    //设置定时器的触发事件
//    dispatch_source_set_event_handler(timer, ^{
//        //倒计时  刷新button上的title ，当倒计时时间为0时，结束倒计时
//        //1. 每调用一次 时间-1s
//        timeout --;
//
//        weakSelf.verCodeWaitTime = timeout;
//
//        //2.对timeout进行判断时间是停止倒计时，还是修改button的title
//        if (timeout <= 0) {
//            //停止倒计时，button打开交互，背景颜色还原，title还原
//            //关闭定时器
//            dispatch_source_cancel(timer);
//            //MRC下需要释放，这里不需要
//            // dispatch_realse(timer);
//            //button上的相关设置
//            //注意: button是属于UI，在iOS中多线程处理时，UI控件的操作必须是交给主线程(主队列)
//            //在主线程中对button进行修改操作
////            dispatch_async(dispatch_get_main_queue(), ^{
////                weakSelf.downBtn.userInteractionEnabled = YES;//开启交互性
////                weakSelf.downBtn.backgroundColor = [UIColor yellowColor];
////                [weakSelf.downBtn setTitle:@"获取验证码" forState:UIControlStateNormal];
////            });
//        }else {
//            //处于正在倒计时，在主线程中刷新button上的title，时间-1秒
////            dispatch_async(dispatch_get_main_queue(), ^{
////                NSString * title = [NSString stringWithFormat:@"%d秒后重新获取验证码",timeout];
////                [weakSelf.downBtn setTitle:title forState:UIControlStateNormal];
////                weakSelf.downBtn.userInteractionEnabled = NO;//关闭交互性
////            });
//        }
//    });
//    dispatch_resume(timer);
//}
//
//- (void)waitGetNewVerCode
//{
//    _newVerCodeWaitTime = 60;
//
//    __block int timeout = _newVerCodeWaitTime + 1;
//    //获取全局队列
//    dispatch_queue_t global = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//    //创建一个定时器，并将定时器的任务交给全局队列执行(并行，不会造成主线程阻塞)
//    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, global);
//    // 设置触发的间隔时间
//    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
//    //1.0 * NSEC_PER_SEC  代表设置定时器触发的时间间隔为1s
//    //0 * NSEC_PER_SEC    代表时间允许的误差是 0s
//
//    //block内部 如果对当前对象的强引用属性修改 应该使用__weak typeof(self)weakSelf 修饰  避免循环调用
//    __weak typeof(self)weakSelf = self;
//    //设置定时器的触发事件
//    dispatch_source_set_event_handler(timer, ^{
//        //倒计时  刷新button上的title ，当倒计时时间为0时，结束倒计时
//        //1. 每调用一次 时间-1s
//        timeout --;
//
//        weakSelf.newVerCodeWaitTime = timeout;
//
//        //2.对timeout进行判断时间是停止倒计时，还是修改button的title
//        if (timeout <= 0) {
//            //停止倒计时，button打开交互，背景颜色还原，title还原
//            //关闭定时器
//            dispatch_source_cancel(timer);
//            //MRC下需要释放，这里不需要
//            // dispatch_realse(timer);
//            //button上的相关设置
//            //注意: button是属于UI，在iOS中多线程处理时，UI控件的操作必须是交给主线程(主队列)
//            //在主线程中对button进行修改操作
//            //            dispatch_async(dispatch_get_main_queue(), ^{
//            //                weakSelf.downBtn.userInteractionEnabled = YES;//开启交互性
//            //                weakSelf.downBtn.backgroundColor = [UIColor yellowColor];
//            //                [weakSelf.downBtn setTitle:@"获取验证码" forState:UIControlStateNormal];
//            //            });
//        }else {
//            //处于正在倒计时，在主线程中刷新button上的title，时间-1秒
//            //            dispatch_async(dispatch_get_main_queue(), ^{
//            //                NSString * title = [NSString stringWithFormat:@"%d秒后重新获取验证码",timeout];
//            //                [weakSelf.downBtn setTitle:title forState:UIControlStateNormal];
//            //                weakSelf.downBtn.userInteractionEnabled = NO;//关闭交互性
//            //            });
//        }
//    });
//    dispatch_resume(timer);
//}

//- (void)userUnBindDevToken
//{
//    /// 发起请求
//    NSString* strHeadImgUrl = self.userInfo.headimgurl == nil ? @"" : self.userInfo.headimgurl;
//
//    [[AFNetWorkUtils racPOSTWthURL:url_interface_updateUser params:[NSString dic2url:interface_param_updateUser(self.userToken, strHeadImgUrl, self.userInfo.nickname, @"")]] subscribeNext:^(id x) {
//        //成功返回(result class is NSDictionary)
//
//    } error:^(NSError *error) {
//        //错误处理
//
//    }];
//}
//
//- (RACSignal*)requestBindDevToken
//{
//    NSString* devToken = [UMManager sharedUMManager].devToken;
//
//    if ([NSString mh_isBlankString:devToken])
//    {
//        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//            [subscriber sendNext:@NO];
//            [subscriber sendCompleted];
//
//            return nil;
//        }];
//    }
//
//    @weakify(self)
//    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//        @strongify(self)
//
//        @weakify(self)
//
//        /// 发起请求
//        NSString* strHeadImgUrl = self.userInfo.headimgurl == nil ? @"" : self.userInfo.headimgurl;
//
//        [[AFNetWorkUtils racPOSTWthURL:url_interface_updateUser params:[NSString dic2url:interface_param_updateUser(self.userToken, strHeadImgUrl, self.userInfo.nickname, devToken)]] subscribeNext:^(id x) {
//            //成功返回(result class is NSDictionary)
//
//            @strongify(self);
//
//            [subscriber sendNext:@(YES)];
//            [subscriber sendCompleted];
//        } error:^(NSError *error) {
//            //错误处理
//
//            [subscriber sendNext:@(NO)];
//            [subscriber sendCompleted];
//        }];
//
//        return nil;
//    }];
//}
//
//- (RACSignal*)requestUserInfo:(NSString*)userToken
//{
//    @weakify(self)
//    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//        @strongify(self)
//
//        @weakify(self)
//        /// 发起请求
//        [[AFNetWorkUtils racPOSTWthURL:url_interface_userMessage params:[NSString dic2url:interface_param_userMessage(userToken)]] subscribeNext:^(id x) {
//            //成功返回(result class is NSDictionary)
//
//            @strongify(self);
//            HDUser* hdLogin = [HDUser modelWithJSON:x[@"result"]];
//
//            self.userInfo = [hdLogin copy];
//
//            [subscriber sendNext:@(YES)];
//            [subscriber sendCompleted];
//        } error:^(NSError *error) {
//            //错误处理
//
//            [subscriber sendNext:@(NO)];
//            [subscriber sendCompleted];
//        }];
//
//        return nil;
//    }];
//}
//
//- (RACSignal*)requestStep
//{
//    @weakify(self)
//    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//        @strongify(self)
//
//        @weakify(self)
//        /// 发起请求
//        [[AFNetWorkUtils racPOSTWthURL:url_interface_step params:[NSString dic2url:interface_param_step(_userToken)]] subscribeNext:^(id x) {
//            //成功返回(result class is NSDictionary)
//
//            @strongify(self);
//            HDStep* step = [HDStep modelWithJSON:x[@"result"]];
//
//            self.step = step;
//
//            [subscriber sendNext:step];
//            [subscriber sendCompleted];
//        } error:^(NSError *error) {
//            //错误处理
//
//            [subscriber sendNext:nil];
//            [subscriber sendCompleted];
//        }];
//
//        return nil;
//    }];
//}
//
//- (void)resetStep:(HDStep*)nStep
//{
//    self.step = nStep;
//}
//
//- (void)userBindSocket
//{
//    self.isUserConnectSocket = YES;
//}
//
//- (void)userUnBindSocket
//{
//    self.isUserConnectSocket = NO;
//}

#pragma mark - Signal
- (RACSignal*)requestUnReadMsgSignal
{
    @weakify(self)
    
    if (![self isHaveUserToken])
    {
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            
            [subscriber sendNext:nil];
            [subscriber sendCompleted];
            
            return nil;
        }];
    }
    
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber)
            {
                @strongify(self)
                
                @weakify(self);
                NSString* strParam = interface_param_getusermessages(0);
                NSString* strReqUrl = HCStrFormat(@"%@%@", url_interface_getusermessages, strParam);
                [[AFNetWorkUtils racGETWthURL:strReqUrl] subscribeNext:^(id x)
                 {
                     @strongify(self)
                     
                     CommonMsgData* comMsgData = [CommonMsgData modelWithJSON:x];
                     
                     self.unReadMsgNum = comMsgData.totalcount;
                     
                     [subscriber sendNext:@YES];
                     [subscriber sendCompleted];
                 }  error:^(NSError *error) {
                     //错误处理
                     
                     [subscriber sendNext:@NO];
                     [subscriber sendCompleted];
                 }];
                
                return nil;
            }];
}

- (RACSignal*)requestCleanUnReadMsgSignal
{
    @weakify(self)
    
    if (![self isHaveUserToken])
    {
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            
            [subscriber sendNext:nil];
            [subscriber sendCompleted];
            
            return nil;
        }];
    }
    
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber)
            {
                @strongify(self)
                
                @weakify(self);
                [[AFNetWorkUtils racGETWthURL:url_interface_readusermessages] subscribeNext:^(id x)
                 {
                     @strongify(self)
                     
                     self.unReadMsgNum = 0;
                     
                     [subscriber sendNext:@YES];
                     [subscriber sendCompleted];
                 }  error:^(NSError *error) {
                     //错误处理
                     
                     [subscriber sendNext:@NO];
                     [subscriber sendCompleted];
                 }];
                
                return nil;
            }];
}

- (RACSignal*)requestUserInfoSignal
{
    @weakify(self)

    if (![self isHaveUserToken])
    {
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            
            [subscriber sendNext:nil];
            [subscriber sendCompleted];
            
            return nil;
        }];
    }

    [self reupdate];

    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber)
            {
                @strongify(self)
                
                @weakify(self);
                [[AFNetWorkUtils racGETWthURL:url_interface_getuserinfo] subscribeNext:^(id x)
                 {
                     @strongify(self)
                     
                     UserData* userData = [UserData modelWithJSON:x];
                     
                     [self saveUserData:userData];
                     
                     NSLog(@"UserInfoSignal - Finish");
                     
                     [subscriber sendNext:@YES];
                     [subscriber sendCompleted];
                 }  error:^(NSError *error) {
                     //错误处理
                     
                     [subscriber sendNext:@NO];
                     [subscriber sendCompleted];
                 }];
                
                return nil;
            }];
}

@end
